package com.hub.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hub.dto.auth.RoleProfileParam;
import com.hub.entity.AuthRole;
import com.hub.entity.AuthRoleMenu;
import com.hub.frame.consts.ConstantUtil;
import com.hub.utils.ApiResultObject;
import com.hub.mapper.AuthMenuMapper;
import com.hub.mapper.AuthRoleMapper;
import com.hub.mapper.AuthRoleMenuMapper;
import com.hub.mapper.AuthUserInfoMapper;
import com.hub.model.auth.RoleProfileVo;
import com.hub.model.auth.TreeBean;
import com.hub.service.IAuthRoleMenuService;
import com.hub.service.IAuthRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hub
 * @since 2020-05-13
 */
@Service
public class AuthRoleServiceImpl extends BaseServiceImpl<AuthRoleMapper, AuthRole> implements IAuthRoleService {

    @Resource
    private AuthRoleMapper authRoleMapper;
    @Resource
    private AuthMenuMapper authMenuMapper;
    @Resource
    private AuthRoleMenuMapper authRoleMenuMapper;
    @Resource
    private AuthUserInfoMapper authUserInfoMapper;
    @Autowired
    private IAuthRoleMenuService authRoleMenuService;

    @Override
    public List<AuthRole> findByUserId(Long userId) {
        return authRoleMapper.selectByUserId(userId);
    }

    @Override
    public IPage<AuthRole> getList(Page<AuthRole> page, AuthRole param) {
        QueryWrapper<AuthRole> wrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(param.getRoleName())){
            wrapper.like("role_name", param.getRoleName());
        }
        wrapper.eq("active_flg", ConstantUtil.YES);
        wrapper.orderByDesc("create_time");
        return this.page(page, wrapper);
    }

    @Override
    public ApiResultObject all() {
        QueryWrapper<AuthRole> wrapper = new QueryWrapper<>();
        wrapper.eq("active_flg", ConstantUtil.YES);
        return ApiResultObject.success(this.list(wrapper));
    }

    @Override
    public List<TreeBean> getTreeBean() {
        return authMenuMapper.selectMenuTree();
    }

    @Override
    public RoleProfileVo getRoleProfile(Long roleId) {
//        List<TreeBean> treeBeans = authMenuMapper.selectProfileTree();
        List<String> profiles = authRoleMenuMapper.selectUserProfile(roleId);
        return new RoleProfileVo(null, profiles);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResultObject create(RoleProfileParam param) {
        //角色名重复check
        QueryWrapper<AuthRole> wrapper = new QueryWrapper<>();
        wrapper.eq("role_name", param.getRoleName());
        int count = this.count(wrapper);
        if(count > 0){
            return ApiResultObject.failed("角色名已存在，请重新输入！");
        }

        //新增角色
        AuthRole authRole = new AuthRole();
        authRole.setRoleName(param.getRoleName());
        authRole.setRemark(param.getRemark());
        this.save(authRole);
        Long roleId = authRole.getId();
        //新增角色权限关系
        List<Long> profiles = param.getProfiles();
        List<Long> profilesRoot = param.getProfilesRoot();
        if ( profiles == null || profiles.isEmpty()) {
            return ApiResultObject.success();
        }
        //查询用户信息
        List<AuthRoleMenu> authRoleMenus = this.getAuthMenuList(profiles, roleId);

        //获取新的角色菜单关系
        if (profilesRoot != null) {
            List<AuthRoleMenu> authMenuRolesRoot = this.getAuthMenuList(profilesRoot, roleId);
            authRoleMenus.addAll(authMenuRolesRoot);
        }
        authRoleMenuService.saveBatch(authRoleMenus);
        return ApiResultObject.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResultObject modify(RoleProfileParam param) {
        Long roleId = param.getRoleId();
        //角色名重复check
        QueryWrapper<AuthRole> wrapper = new QueryWrapper<>();
        wrapper.eq("role_name", param.getRoleName());
        wrapper.ne("id", roleId);
        int count = this.count(wrapper);
        if(count > 0){
            return ApiResultObject.failed("角色名已存在，请重新输入！");
        }

        //更新角色信息
        AuthRole authRole = this.getById(roleId);
        authRole.setRoleName(param.getRoleName());
        authRole.setRemark(param.getRemark());
        authRole.setActiveFlg(ConstantUtil.YES);
        this.updateById(authRole);

        //先删除角色菜单关系表
        authRoleMenuMapper.deleteByRoleId(roleId);
        List<Long> profiles = param.getProfiles();
        List<Long> profilesRoot = param.getProfilesRoot();
        if ( profiles == null || profiles.isEmpty()) {
            return ApiResultObject.success();
        }
        //查询用户信息
        List<AuthRoleMenu> authRoleMenus = this.getAuthMenuList(profiles, roleId);

        //获取新的角色菜单关系
        if (profilesRoot != null) {
            List<AuthRoleMenu> authMenuRolesRoot = this.getAuthMenuList(profilesRoot, roleId);
            authRoleMenus.addAll(authMenuRolesRoot);
        }
        authRoleMenuService.saveBatch(authRoleMenus);
        return ApiResultObject.success();
    }

    @Override
    public ApiResultObject delete(RoleProfileParam param) {
        Long roleId = param.getRoleId();
        this.removeById(roleId);
        return ApiResultObject.success();
    }

    /**
     * 获取新的角色菜单关系
     * @param profiles
     * @param roleId
     * @return
     */
    private List<AuthRoleMenu> getAuthMenuList(List<Long> profiles, Long roleId){
        return profiles.stream().map(menuId -> {
            AuthRoleMenu authRoleMenu = new AuthRoleMenu();
            authRoleMenu.setRoleId(roleId);
            authRoleMenu.setMenuId(menuId);
            authRoleMenu.setActiveFlg(ConstantUtil.YES);
            return authRoleMenu;
        }).collect(Collectors.toList());
    }
}
